package yl.hs.bmipfull.service.production.impl;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yl.hs.bmipfull.annotations.DBTable;
import yl.hs.bmipfull.daos.laboratory.IProductCateDao;
import yl.hs.bmipfull.daos.laboratory.IProductInfoDao;
import yl.hs.bmipfull.daos.production.IFinishProductInventoryDao;
import yl.hs.bmipfull.daos.production.IFinishProductWarehouseRecordDao;
import yl.hs.bmipfull.daos.salemanage.ISaleContractDao;
import yl.hs.bmipfull.daos.salemanage.ISaleContractProductsDao;
import yl.hs.bmipfull.daos.salemanage.ISaleOrderPlaceDetailDao;
import yl.hs.bmipfull.daos.system.ICoreDataTagDao;
import yl.hs.bmipfull.pojo.production.FinishProductInventoryEntity;
import yl.hs.bmipfull.pojo.production.ProductionDispatchLogEntity;
import yl.hs.bmipfull.pojo.system.RoleInfoEntity;
import yl.hs.bmipfull.service.laboratory.IPackageInfoService;
import yl.hs.bmipfull.service.production.IFinishProductInventoryService;
import yl.hs.bmipfull.utils.DataState;
import yl.hs.bmipfull.utils.HsApp;
import yl.hs.bmipfull.utils.Tl;
import yl.hs.bmipfull.utils.datastate.ActionType;
import yl.hs.bmipfull.viewmodels.PageQuery;
import yl.hs.bmipfull.viewmodels.PageResult;
import yl.hs.bmipfull.viewmodels.chart.BrandInventoryModel;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 谢东
 * @apiNote 成品仓库库存服务层接口实现
 * @since 2023年06月14日 15时02分03秒 <br/>
 */
@Service
public class FinishProductInventoryServiceImpl extends ProductionBaseService implements IFinishProductInventoryService {

    @Autowired
    IFinishProductInventoryDao dao;

    @Autowired
    private IPackageInfoService packageInfoService;
    @Autowired
    IProductCateDao cateDao;
    @Autowired
    IProductInfoDao infoDao;
    @Autowired
    ICoreDataTagDao tagDao;
    @Autowired
    ISaleContractProductsDao productsDao;
    @Autowired
    ISaleContractDao contractDao;
    @Autowired
    ISaleOrderPlaceDetailDao detailDao;
    @Autowired
    IFinishProductWarehouseRecordDao recordDao;
    @Override
    public List<FinishProductInventoryEntity> queryList(PageQuery pageQuery) throws Exception {
        pageQuery.checkSortSides(FinishProductInventoryEntity.class);
        return dao.queryPage(pageQuery.getQuery());
    }

    @Override
    public PageResult<Object> queryPage(PageQuery pageQuery, int rowNum, int page) throws Exception {
        var user = HsApp.getCurrent();
        pageQuery.checkSortSides(FinishProductInventoryEntity.class);
        var totil = queryList(pageQuery);
        pageQuery.getQuery().put("querySkip", (page - 1) * rowNum);
        pageQuery.getQuery().put("pageSize", rowNum);
        PageResult<Object> result = new PageResult(rowNum);
        if(user!=null){
            var tags = tagDao.queryBySN(user.getUserSN().split(","));
            var roleCode = Tl.getDBMapCode(RoleInfoEntity.class);
            var roles = tags.stream().filter(p -> p.getTagType().equals(roleCode) && p.getMainSN().equals(user.getUserSN())).map(p -> p.getTagSN()).collect(Collectors.toList());
            if(roles.contains("ROLE230712000016")){
                var contract =  contractDao.queryBySaleSN(user.getUserSN());
                if(contract!=null && contract.size()>0){
                    var contractSN = contract.stream().map(s->s.getSn()).collect(Collectors.toList());
                    var productSN =  productsDao.queryByContractSN(contractSN);
                    pageQuery.getQuery().put("productSNList", productSN);
                }else{
                    List<String> qu = new ArrayList<>();
                    qu.add("123");
                    pageQuery.getQuery().put("productSNList",qu);
                }
            }
        }
        result.setRecords(dao.queryCountByCondition(pageQuery.getQuery()));
        result.setPage(page);
        List<FinishProductInventoryEntity> products = dao.queryPage(pageQuery.getQuery());
        for (FinishProductInventoryEntity product : products) {
            product.setPackWeight(packageInfoService.findBySn(product.getPackageSN()).getPackWeight());
        }
        List<Object> data = new ArrayList<>();
        for (FinishProductInventoryEntity product : products) {
            var map = product.toMap();
            var entity = infoDao.findBySN(product.getProductSN());
            if(entity!=null){
                map.put("prouctCateName",cateDao.findBySN(entity.getProductCateSN()).getCateName());
                map.put("prouctCateSN",cateDao.findBySN(entity.getProductCateSN()).getSn());
            }
            var saledetail = detailDao.queryListByState(product.getProductSN());
            var wei = recordDao.queryByTypeAndProduct(2,product.getProductSN(),1);
            map.put("DeliveryQuantity",saledetail.add(wei));
            data.add(map);
        }
        result.setData(data);
        Map<String,Object> title = new HashMap<>();
        title.put("weight",totil.stream().map(FinishProductInventoryEntity::getWeight).reduce(BigDecimal::add));
        title.put("quantity",totil.stream().map(FinishProductInventoryEntity::getQuantity).reduce(BigDecimal::add));
        result.setObject(title);
        return result;
    }


    @Override
    public FinishProductInventoryEntity findBySn(String sn) {
        return dao.findBySN(sn);
    }
    @Scheduled(cron = "0 0 23 * * ?")
    @Override
    public Integer insertInventory() {
        var list = dao.queryAll();
        var log = new ProductionDispatchLogEntity();
        list.forEach(s->{
            log.setContent("创建每日盘存记录库存，库存从" + s.getWeight().setScale(2, RoundingMode.DOWN) + "变为" + s.getWeight().setScale(2, RoundingMode.DOWN) + ",系统自动盘存");
            log.setUserSN("");
            log.setUserName("系统");
            log.setActionType((short) 500);
            log.setHandleTime(new Date());
            log.setTypeName("成品仓库库存");
            log.setTypeCode(FinishProductInventoryEntity.class.getAnnotation(DBTable.class).mapCode());
            log.setDataSN(s.getSn());
            logDao.insertNew(log);
        });
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveFinishProductInventory(Map<String, Object> model, String sn) throws Exception {
        Integer result = 0;
        FinishProductInventoryEntity entity = null;
        if (Tl.isEmpty(sn)) {
            //执行保存
            entity = new FinishProductInventoryEntity();
            Tl.getChangeLog(entity, model);
            entity.setPYFieldValue();
            entity.setSn(queryNewSN(FinishProductInventoryEntity.class));
            result = dao.insertNew(entity);
            if (result > 0) {
                writeLog(ActionType.CREATE, entity.getSn(), "插入成品仓库库存信息", Tl.toJson(entity), FinishProductInventoryEntity.class);
            }

        } else {
            //执行修改
            entity = findBySn(sn);
            Tl.getChangeLog(entity, model);
            entity.setPYFieldValue();
            result = dao.update(entity);
            if (result > 0) {
                writeLog(ActionType.UPDATE, sn, "更新成品仓库库存信息", Tl.toJson(entity), FinishProductInventoryEntity.class);
            }
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer delete(String sn) {
        var sns = sn.split(",");
        Integer result = dao.changeStateBySN(sns, DataState.DELETED.code);
        if (result > 0) {
            writeLog(ActionType.DELETE, sns, FinishProductInventoryEntity.class);
        }
        return result;
    }

    @Override
    public List<Object> quantityByProductSN(String productSN) {
        var result = dao.quantityByProductSN(productSN);
        List<Object> data = new ArrayList<>();
        result.forEach(s->{
            var product = infoDao.findBySN(s.getProductSN());
            var map = s.toMap();
            if(product!=null){
                var cate = cateDao.findBySN(product.getProductCateSN());
                if(cate!=null){
                    map.put("productCateName",cate.getCateName());
                    data.add(map);
                }
            }
        });
        return data;
    }

    @Override
    public List<FinishProductInventoryEntity> findByProductSN(String productSN, String packageName, String packageSN) {
        return dao.findByProductSN(productSN,packageName,packageSN);
    }

    @Override
    public List<FinishProductInventoryEntity> findByProductSNAndWareHouseSN(String productSN, String packageName, String packageSN, String wareHouseSN) {
        return dao.findByProductSNAndWareHouseSN(productSN,packageName,packageSN,wareHouseSN);
    }

    @Override
    public List<BrandInventoryModel> queryBrandInventory() {
        return dao.queryBrandInventory();
    }

    @Override
    public List<BrandInventoryModel> queryBrandByCateName(String cateSN) {
        return dao.queryBrandByCateName(cateSN);
    }
}